#!/usr/bin/env python
# -*- coding:utf-8 -*-
import uuid
import os
import sys
import pickle
from requests import post
from utils import GenerateRegisterFile as Generate
from utils import MD5

reg = "registry.conf"
ser_url = "http://192.168.1.105:8001/check/setup/"


class PreventingPirate(object):
    """
    PreventingPirate object according to anti-piracy requirements

    This module provides anti-piracy method for installation package
    """
    def check_registry(self):
        """
        Check local registry information and service information
        :return: check result, bool, True is installed, False is not
        """
        try:
            _dict = SerializerDeSerializer.deserilizer(reg)
            print(_dict.__str__())
            if not dict:  # Can't get information, quit install
                return True
            elif _dict["cpu_id"] or _dict["mac"] or _dict["motherboard_serial"] or _dict["network"]:
                """
                If already had some information about machine,
                Quit the installation process
                """
                return True
            elif _dict["package_id"] and not _dict["cpu_id"] and not _dict["mac"] \
                    and not _dict["motherboard_serial"] and not _dict["network"]:
                """
                if have package id only, write machine information into registry
                file and connected to the server check information
                """
                obj_machine_info = self.get_machine_info()
                obj_machine_info.package_id = _dict["package_id"]

                SerializerDeSerializer.serializer(obj_machine_info, reg)

                # ######################################>>>>>>>>>>>>> 判断返回值
                # for shupup
                _dict = obj_machine_info.__str__()
                print(_dict)
                print("="*20)
                _dict["cpu_id"] = _dict["cpu_id"]
                _dict["motherboard_serial"] = _dict["motherboard_serial"]
                return self.check_service_info(_dict)

        except FileNotFoundError as e:
            print(e)

    def check_service_info(self, params):
        """
        Check service information, we still need to send all message to server
        :param package_id:
        :return:
        """
        # {"username": "123456789", "password": "20eabe5d64b0e216796e834f52d61fd0b70332fc"}
        resp = post(url=ser_url, json=params)  # put(url=ser_url, data=params)

        characters = resp.content.decode('UTF-8')
        characters = characters.strip()
        if characters == 'true':
            return True
        if characters == 'false':
            return False
        return True

    def get_mac_address(self):
        """
        Obtain node's MAC
        :return:
        """
        mac = uuid.UUID(int=uuid.getnode()).hex[-12:]
        return ":".join([mac[e:e+2] for e in range(0, 11, 2)]).strip()

    def get_cpu_id(self):
        """
        Obtain cpu id
        :return:
        """
        f = os.popen("sudo dmidecode -t 1 | grep ID")  # centos

        cpu_id = f.readline().strip()
        if not cpu_id:
            f = os.popen("sudo dmidecode -t 4 | grep ID")  # ubuntu
            cpu_id = f.readline().strip()
            if cpu_id:
                return cpu_id.strip()
            else:
                """
                If we cant't find cpuid, we return a random number?
                """
                return "Can not find cpu id"
        elif cpu_id:
            return cpu_id.strip()

    def get_motherboard_information(self):
        """
        Obtain motherboard information
        :return:
        """
        f = os.popen("sudo dmidecode -t 1 | grep Serial")
        motherboard_information_id = f.readline()

        if not motherboard_information_id:
            f = os.popen("sudo dmidecode -t 2 | grep Serial")
            motherboard_information_id = f.readline()
            if not motherboard_information_id:
                return motherboard_information_id.strip()

            else:
                """
                If we cant't find motherboard information id, we return a random number?
                """
                return "Motherboard Serial Can Not Find"

        elif motherboard_information_id:
            return motherboard_information_id.strip()

    def get_linux_network(self):
        network_list = os.popen("curl members.3322.org/dyndns/getip").readlines()
        try:
            return network_list[0].strip()
        except IndexError as e:
            print(e)

    def get_machine_info(self):
        cpu_id = MD5.encryption(self.get_cpu_id())
        mac = self.get_mac_address()
        motherboard_serial = MD5.encryption(self.get_motherboard_information())
        network = self.get_linux_network()

        return RegistryInformation(
            cpu_id=cpu_id,
            mac=mac,
            motherboard_serial=motherboard_serial,
            network=network
        )


class RegistryInformation(object):
    """
    This class is used for persistence registry information
    """
    def __init__(self, package_id="", cpu_id="", mac="", motherboard_serial="", network=""):
        self.package_id = package_id
        self.cpu_id = cpu_id
        self.mac = mac
        self.motherboard_serial = motherboard_serial
        self.network = network

    def __str__(self):
        return {
            "package_id": self.package_id,
            "cpu_id": self.cpu_id,
            "mac": self.mac,
            "motherboard_serial": self.motherboard_serial,
            "network": self.network
            }


class SerializerDeSerializer(object):
    """
    provide serializer tool
    """
    @classmethod
    def serializer(cls, obj, file):
        try:
            conf = open(file, "wb")
            # serializer = pickle.dumps(ri)
            pickle.dump(obj=obj, file=conf)
            conf.close()
        except FileNotFoundError as e:
            print(e)
            return True
        else:
            conf.close()

    @classmethod
    def deserilizer(cls, file):
        try:
            conf = open(file, "rb")
            deserializer = pickle.load(conf, encoding="utf-8")
            return {"package_id": deserializer.package_id,
                    "cpu_id": deserializer.cpu_id,
                    "mac": deserializer.mac,
                    "motherboard_serial": deserializer.motherboard_serial,
                    "network": deserializer.network}
        except FileNotFoundError as e:
            print(e)
            return True
        else:
            conf.close()


def check_registry():
    """
        Check registry information
        :return result: If installation package has been used return True, else return False
        """
    p = PreventingPirate()
    return p.check_registry()


def generate_package_uuid():
    """
        Install uuid into installation package
        :return:
        """
    ri = RegistryInformation("b5011bac-cb91-47ee-9bac-718bfc72e917", "", "", "", "")
    Generate.generate(reg, ri)


if __name__ == "__main__":
    # generate_package_uuid()
    # print(SerializerDeSerializer.deserilizer(reg))
    print(check_registry())
    #  a = Information(package_id="b5011bac-cb91-47ee-9bac-718bfc72e917")


